/**
 * 工程知识库管理器 - 保存、加载和使用知识库
 */

import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
import { Logger } from '../../../../src/logger/Logger';
import { ProjectKnowledgeCollector, KnowledgeBase, ProjectInfo } from './ProjectKnowledgeCollector';

export class ProjectKnowledgeManager {
    private static instance: ProjectKnowledgeManager;
    private knowledgeBase: KnowledgeBase | null = null;
    private readonly knowledgeFilePath: string;
    
    private constructor() {
        // 知识库保存在用户主目录的 .harmonypilot/project-knowledge.json
        const homeDir = os.homedir();
        const harmonypilotDir = path.join(homeDir, '.harmonypilot');
        
        // 确保目录存在
        if (!fs.existsSync(harmonypilotDir)) {
            fs.mkdirSync(harmonypilotDir, { recursive: true });
        }
        
        this.knowledgeFilePath = path.join(harmonypilotDir, 'project-knowledge.json');
        
        Logger.info(`[ProjectKnowledgeManager] 知识库路径: ${this.knowledgeFilePath}`);
    }
    
    public static getInstance(): ProjectKnowledgeManager {
        if (!ProjectKnowledgeManager.instance) {
            ProjectKnowledgeManager.instance = new ProjectKnowledgeManager();
        }
        return ProjectKnowledgeManager.instance;
    }
    
    /**
     * 学习工程结构并保存
     */
    async learnAndSave(
        directoryPath: string,
        progressCallback?: (message: string, progress: number) => void
    ): Promise<void> {
        Logger.info(`[ProjectKnowledgeManager] 📚 开始学习并保存工程结构`);
        
        const collector = new ProjectKnowledgeCollector();
        this.knowledgeBase = await collector.learnFromDirectory(directoryPath, progressCallback);
        
        // 保存到文件
        try {
            const json = JSON.stringify(this.knowledgeBase, null, 2);
            fs.writeFileSync(this.knowledgeFilePath, json, 'utf-8');
            
            Logger.info(`[ProjectKnowledgeManager] ✅ 知识库已保存`);
            Logger.info(`[ProjectKnowledgeManager]    位置: ${this.knowledgeFilePath}`);
            Logger.info(`[ProjectKnowledgeManager]    大小: ${(json.length / 1024).toFixed(2)} KB`);
        } catch (error) {
            Logger.error(`[ProjectKnowledgeManager] ❌ 保存知识库失败: ${error}`);
            throw error;
        }
    }
    
    /**
     * 加载知识库
     */
    async load(): Promise<KnowledgeBase | null> {
        if (this.knowledgeBase) {
            return this.knowledgeBase;
        }
        
        if (!fs.existsSync(this.knowledgeFilePath)) {
            Logger.info(`[ProjectKnowledgeManager] ⚠️ 知识库文件不存在，尚未学习任何工程`);
            return null;
        }
        
        try {
            const json = fs.readFileSync(this.knowledgeFilePath, 'utf-8');
            this.knowledgeBase = JSON.parse(json);
            
            Logger.info(`[ProjectKnowledgeManager] ✅ 知识库已加载`);
            Logger.info(`[ProjectKnowledgeManager]    工程数量: ${this.knowledgeBase?.projects.length || 0}`);
            Logger.info(`[ProjectKnowledgeManager]    最后更新: ${this.knowledgeBase?.lastUpdated}`);
            
            return this.knowledgeBase;
        } catch (error) {
            Logger.error(`[ProjectKnowledgeManager] ❌ 加载知识库失败: ${error}`);
            return null;
        }
    }
    
    /**
     * 获取知识库（如果未加载则尝试加载）
     */
    async getKnowledgeBase(): Promise<KnowledgeBase | null> {
        if (!this.knowledgeBase) {
            await this.load();
        }
        return this.knowledgeBase;
    }
    
    /**
     * 清除知识库
     */
    clear(): void {
        this.knowledgeBase = null;
        
        if (fs.existsSync(this.knowledgeFilePath)) {
            fs.unlinkSync(this.knowledgeFilePath);
            Logger.info(`[ProjectKnowledgeManager] ✅ 知识库已清除`);
        }
    }
    
    /**
     * 查找最相关的工程（基于当前源文件路径）
     */
    async findRelevantProject(sourceFilePath: string): Promise<ProjectInfo | null> {
        const kb = await this.getKnowledgeBase();
        
        if (!kb || kb.projects.length === 0) {
            return null;
        }
        
        // 找到源文件所在的工程根目录
        let currentPath = path.dirname(sourceFilePath);
        const maxDepth = 10;
        let depth = 0;
        
        while (depth < maxDepth) {
            // 检查是否是某个已学习工程的根目录
            const matchingProject = kb.projects.find(p => p.rootPath === currentPath);
            if (matchingProject) {
                Logger.info(`[ProjectKnowledgeManager] ✅ 找到匹配工程: ${matchingProject.name}`);
                return matchingProject;
            }
            
            // 向上查找
            const parentPath = path.dirname(currentPath);
            if (parentPath === currentPath) {
                break;  // 已到根目录
            }
            currentPath = parentPath;
            depth++;
        }
        
        // 如果找不到精确匹配，返回第一个工程作为参考
        Logger.info(`[ProjectKnowledgeManager] ⚠️ 未找到精确匹配的工程，使用第一个工程作为参考`);
        return kb.projects[0];
    }
    
    /**
     * 格式化知识库为 LLM Prompt
     */
    formatForLLM(sourceFilePath: string, kb?: KnowledgeBase): string {
        if (!kb && !this.knowledgeBase) {
            return '';
        }
        
        const knowledgeBase = kb || this.knowledgeBase!;
        
        let prompt = `\n# 📚 项目工程知识库\n\n`;
        prompt += `> 已学习 ${knowledgeBase.projects.length} 个工程的结构和规范\n`;
        prompt += `> 最后更新: ${new Date(knowledgeBase.lastUpdated).toLocaleString('zh-CN')}\n\n`;
        
        // 全局规范
        prompt += `## 🌐 全局规范（所有工程共同遵循的模式）\n\n`;
        
        if (knowledgeBase.globalPatterns.testFileNaming.length > 0) {
            prompt += `### 测试文件命名规范\n`;
            knowledgeBase.globalPatterns.testFileNaming.forEach(pattern => {
                prompt += `- \`${pattern}\`\n`;
            });
            prompt += `\n`;
        }
        
        if (knowledgeBase.globalPatterns.testDirectories.length > 0) {
            prompt += `### 测试目录结构\n`;
            knowledgeBase.globalPatterns.testDirectories.slice(0, 5).forEach(dir => {
                prompt += `- \`${dir}/\`\n`;
            });
            if (knowledgeBase.globalPatterns.testDirectories.length > 5) {
                prompt += `- ... 还有 ${knowledgeBase.globalPatterns.testDirectories.length - 5} 个\n`;
            }
            prompt += `\n`;
        }
        
        if (knowledgeBase.globalPatterns.commonTestFrameworks.length > 0) {
            prompt += `### 常用测试框架\n`;
            knowledgeBase.globalPatterns.commonTestFrameworks.forEach(fw => {
                prompt += `- ${fw}\n`;
            });
            prompt += `\n`;
        }
        
        // 查找当前文件所属的工程
        const currentProject = knowledgeBase.projects.find(p => 
            sourceFilePath.startsWith(p.rootPath)
        );
        
        if (currentProject) {
            prompt += `## 🎯 当前工程: ${currentProject.name}\n\n`;
            prompt += this.formatProjectInfo(currentProject);
        } else {
            // 如果找不到当前工程，展示一个示例工程
            prompt += `## 📖 参考工程示例\n\n`;
            const exampleProject = knowledgeBase.projects[0];
            if (exampleProject) {
                prompt += this.formatProjectInfo(exampleProject);
            }
        }
        
        prompt += `\n---\n\n**💡 请严格遵循以上工程规范生成测试代码，确保生成的代码与现有代码风格一致。**\n\n`;
        
        return prompt;
    }
    
    /**
     * 格式化单个工程信息
     */
    private formatProjectInfo(project: ProjectInfo): string {
        let info = `### 工程信息\n`;
        info += `- **名称**: ${project.name}\n`;
        info += `- **路径**: \`${project.rootPath}\`\n\n`;
        
        // bundle.json 信息
        if (project.bundleJson) {
            info += `### bundle.json 配置\n`;
            info += `\`\`\`json\n`;
            info += JSON.stringify(project.bundleJson, null, 2);
            info += `\n\`\`\`\n\n`;
        }
        
        // 测试文件示例
        if (project.files.testFiles.length > 0) {
            info += `### 测试文件示例（参考编写风格）\n\n`;
            
            const exampleCount = Math.min(2, project.files.testFiles.length);
            for (let i = 0; i < exampleCount; i++) {
                const testFile = project.files.testFiles[i];
                info += `#### \`${testFile.relativePath}\`\n\n`;
                
                if (testFile.content) {
                    const lines = testFile.content.split('\n').slice(0, 50);
                    info += `\`\`\`cpp\n${lines.join('\n')}\n`;
                    if (testFile.content.split('\n').length > 50) {
                        info += `... (省略剩余内容)\n`;
                    }
                    info += `\`\`\`\n\n`;
                } else if (testFile.summary) {
                    info += `\`\`\`cpp\n${testFile.summary}\n\`\`\`\n\n`;
                }
            }
        }
        
        // BUILD.gn 示例
        if (project.files.buildGnFiles.length > 0) {
            info += `### BUILD.gn 配置示例\n\n`;
            
            const exampleCount = Math.min(2, project.files.buildGnFiles.length);
            for (let i = 0; i < exampleCount; i++) {
                const gnFile = project.files.buildGnFiles[i];
                info += `#### \`${gnFile.relativePath}\`\n\n`;
                
                if (gnFile.content) {
                    info += `\`\`\`gn\n${gnFile.content}\n\`\`\`\n\n`;
                } else if (gnFile.summary) {
                    info += `\`\`\`gn\n${gnFile.summary}\n\`\`\`\n\n`;
                }
            }
        }
        
        // 工程模式分析
        if (project.patterns.testFileNaming.length > 0 || 
            project.patterns.testFrameworks.length > 0) {
            info += `### 工程规范\n`;
            
            if (project.patterns.testFileNaming.length > 0) {
                info += `- **测试文件命名**: ${project.patterns.testFileNaming.join(', ')}\n`;
            }
            
            if (project.patterns.testFrameworks.length > 0) {
                info += `- **测试框架**: ${project.patterns.testFrameworks.join(', ')}\n`;
            }
            
            if (project.patterns.commonIncludes.length > 0) {
                info += `- **常用头文件**: ${project.patterns.commonIncludes.slice(0, 10).join(', ')}\n`;
                if (project.patterns.commonIncludes.length > 10) {
                    info += `  ... 还有 ${project.patterns.commonIncludes.length - 10} 个\n`;
                }
            }
            
            info += `\n`;
        }
        
        return info;
    }
    
    /**
     * 获取知识库统计信息
     */
    async getStatistics(): Promise<{
        hasKnowledge: boolean;
        projectCount: number;
        lastUpdated?: string;
        learningDirectory?: string;
        totalFiles: number;
    }> {
        const kb = await this.getKnowledgeBase();
        
        if (!kb) {
            return {
                hasKnowledge: false,
                projectCount: 0,
                totalFiles: 0
            };
        }
        
        let totalFiles = 0;
        for (const project of kb.projects) {
            totalFiles += project.files.gniFiles.length;
            totalFiles += project.files.headerFiles.length;
            totalFiles += project.files.sourceFiles.length;
            totalFiles += project.files.testFiles.length;
            totalFiles += project.files.fuzzFiles.length;
            totalFiles += project.files.buildGnFiles.length;
        }
        
        return {
            hasKnowledge: true,
            projectCount: kb.projects.length,
            lastUpdated: kb.lastUpdated,
            learningDirectory: kb.learningDirectory,
            totalFiles
        };
    }
}

